package com.spbdx.web.controller.app;

import com.alibaba.fastjson2.JSONObject;
import com.spbdx.common.constant.CacheConstants;
import com.spbdx.common.core.controller.BaseController;
import com.spbdx.common.core.domain.AjaxResult;
import com.spbdx.common.core.domain.entity.SysUser;
import com.spbdx.common.core.domain.model.LoginUser;
import com.spbdx.common.core.redis.RedisCache;
import com.spbdx.common.exception.ServiceException;
import com.spbdx.common.utils.StringUtils;
import com.spbdx.common.utils.WXUtils;
import com.spbdx.framework.config.ServerConfig;
import com.spbdx.framework.web.service.TokenService;
import com.spbdx.system.mapper.SysUserMapper;
import com.spbdx.system.service.ISysConfigService;
import com.spbdx.system.service.ISysRoleService;
import com.spbdx.system.service.ISysUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.Set;

/**
 * Description 小程序授权获取游客信息
 *
 * @author chenwei
 * @version 1.0
 * @date 2023/2/20 10:23
 */
@RestController
@RequestMapping("/wechat/auth")
@Api(tags = "小程序/授权")
public class AuthorizationController extends BaseController {

    @Resource
    private ISysUserService sysUserService;

    @Autowired
    private TokenService tokenService;

    @Resource
    private ISysConfigService sysConfigService;

    @Autowired
    private ServerConfig serverConfig;

    @Resource
    private ISysRoleService roleService;

    @Autowired
    private SysUserMapper userMapper;

    @Resource
    private RedisCache redisCache;

    @ApiOperation("小程序通过授权手机号获取后端token")
    @GetMapping("/phone")
    public AjaxResult getPhone(String code) {
        String appid = sysConfigService.selectConfigByKey("uni-app.appid");
        String secret = sysConfigService.selectConfigByKey("uni-app.secret");
        JSONObject jsonObject = WXUtils.getUserPhonenumber(appid, secret, code);
        if (Objects.isNull(jsonObject)) {
            throw new ServiceException("授权失败");
        }
        if (0 != jsonObject.getIntValue("errcode")) {
            throw new ServiceException("授权失败:" + jsonObject.getString("errmsg"));
        }
        JSONObject phoneInfoObj = jsonObject.getJSONObject("phone_info");
        String phone = phoneInfoObj.getString("phoneNumber");
        List<SysUser> sysUsers = sysUserService.selectUserByPhone(phone);
        if (Objects.isNull(sysUsers) || sysUsers.size() == 0) {
            return AjaxResult.error("用户未授权");
        }
        SysUser user = sysUsers.get(0);
        JSONObject rtn = new JSONObject();
        rtn.put("token", createToken(user.getUserId()));
        return AjaxResult.success(rtn);
    }


    @ApiOperation("小程序获取个人信息")
    @GetMapping("/userInfo")
    public AjaxResult getUserInfo() {
        SysUser sysUser = sysUserService.selectUserById(super.getUserId());
        if (Objects.isNull(sysUser)) {
            throw new ServiceException("未找到用户信息");
        }
        if (StringUtils.isEmpty(sysUser.getAvatar())) {
            sysUser.setAvatar(serverConfig.getUrl() + "/profile/wechat/head.png");
        } else {
            sysUser.setAvatar(serverConfig.getUrl() + sysUser.getAvatar());
        }
        return AjaxResult.success(sysUser);
    }

    /**
     * 小程序wx.login
     *
     * @param code
     * @return
     * @throws Exception
     */
    @ApiOperation("小程序调用wx.login更新openid,unionid并保存到用户表中")
    @GetMapping("/openid")
    public AjaxResult wxLogin(@RequestParam(name = "code") String code) {
        String appid = sysConfigService.selectConfigByKey("uni-app.appid");
        String secret = sysConfigService.selectConfigByKey("uni-app.secret");
        JSONObject obj = WXUtils.certificateVerification(appid, secret, code);
        if (Objects.nonNull(obj) && 0 == obj.getLongValue("errcode")) {
            SysUser sysUser = new SysUser();
            sysUser.setUserId(getUserId());
            sysUser.setOpenid(obj.getString("openid"));
            sysUser.setUnionid(obj.getString("unionid"));
            Set<HashMap<String, String>> set = redisCache.getCacheSet(CacheConstants.WX_FOCUS_USERS);
            if (CollectionUtils.isNotEmpty(set)) {
                set.forEach(map -> {
                    String unionid = map.get("unionid");
                    if (StringUtils.equals(unionid, sysUser.getUnionid())) {
                        sysUser.setOpenid2(map.get("openid"));
                    }
                });
            }
            userMapper.updateUser(sysUser);
        }
        return AjaxResult.success();
    }

    /**
     * 创建token
     *
     * @param userId
     * @return
     */
    private String createToken(Long userId) {
        SysUser sysUser = sysUserService.selectUserById(userId);
        sysUser.setRoles(roleService.selectWechatRoles(userId));
        LoginUser loginUser = new LoginUser();
        loginUser.setUserId(userId);
        loginUser.setDeptId(sysUser.getDeptId());
        loginUser.setUser(sysUser);
        String token = tokenService.createToken(loginUser);
        return token;
    }
}